package com.jweb.framework.mvc;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jweb.framework.bean.BeanHandle;
import com.jweb.framework.core.fault.InitializationError;
import com.jweb.framework.mvc.action.Handler;
import com.jweb.framework.mvc.action.Requester;
import com.jweb.framework.mvc.annotation.Controller;
import com.jweb.framework.mvc.annotation.Request;

public class ActionHandle {
	private static final Logger logger = LoggerFactory.getLogger(ActionHandle.class);
	private static final Map<Requester, Handler> actionMap = new LinkedHashMap<Requester, Handler>();
	static {
		try {
			Set<Class<?>> beanSet = BeanHandle.beanSet;
			for (Class<?> cls : beanSet) {
				if (cls.isAnnotationPresent(Controller.class)) {
					Map<Requester, Handler> commonActionMap = new HashMap<Requester, Handler>();
					// 遍历 Action 类
					Method[] actionMethods = cls.getDeclaredMethods();
					for (Method actionMethod : actionMethods) {
						handleActionMethod(cls, actionMethod, commonActionMap);
					}
					actionMap.putAll(commonActionMap);
				}
			}

		} catch (Exception e) {
			logger.error("Action 初始化失败：", e);
			throw new InitializationError(e);
		}
	}

	private static void handleActionMethod(Class<?> actionClass, Method actionMethod, Map<Requester, Handler> commonActionMap) {
		// 判断当前 Action 方法是否带有 Request 注解
		String actionPath = null, requestMethod = null;
		if (actionMethod.isAnnotationPresent(Request.Get.class)) {
			actionPath = actionMethod.getAnnotation(Request.Get.class).value();
			requestMethod = "GET";
		} else if (actionMethod.isAnnotationPresent(Request.Post.class)) {
			actionPath = actionMethod.getAnnotation(Request.Post.class).value();
			requestMethod = "POST";
		} else if (actionMethod.isAnnotationPresent(Request.Put.class)) {
			actionPath = actionMethod.getAnnotation(Request.Put.class).value();
			requestMethod = "PUT";
		} else if (actionMethod.isAnnotationPresent(Request.Delete.class)) {
			actionPath = actionMethod.getAnnotation(Request.Delete.class).value();
			requestMethod = "DELETE";
		}
		actionMethod.setAccessible(true); // 取消类型安全检测（可提高反射性能）
		commonActionMap.put(new Requester(requestMethod, actionPath), new Handler(actionClass, actionMethod, actionPath));
		logger.info("\tAction:[{}]{}:{}.{}", requestMethod, actionPath, actionClass.getName(), actionMethod.getName());
	}

	/**
	 * 获取 Action Map
	 */
	public static Map<Requester, Handler> getActionMap() {
		return actionMap;
	}
}
